OpenRoads Designer CONNECT Edition SDK Help

Corridor items template drop creator

Description

  • This is a custom interactive tool for assigning template drop to a corridor.

  • The user is prompted for corridor selection and start and end distance along corridor. Later on user needs to click anywhere on UI to use the active template from template library.

  • The CorridorItemsTemplateDropCreator class which extends DgnElementSetTool which handles different events to interact with UI, the CorridorItemsTemplateDropCreator class overrides the events here in this tool .

  • The method OnPostLocate() handles the corridor selection from UI, DoGetTemplate() uses active template from template library, CreateTemplateDrop() adds a template drop to selected corridor.

Remarks

  • This sample code is a part of ManagedSDKExample with a which you get with SDK installation under "examples" section in SDK installation directory.

  • This code is not exact same as in ManagedSDKExample , it is modified for template selection, active template is used here to add to corridor.

  • If you encounter any error while using DgnElementSetTool class, make sure to add a reference to Bentley.DgnDisplayNet.dll by selecting Project > Add Reference or change the projects .csproj file to add reference to this dll .

  • The default dll location will be "C:\Program Files\Bentley\OpenRoads Designer CE 10.11\OpenRoadsDesigner\Bentley.DgnDisplayNet.dll".

Source Code


//Required References
using System;
using Bentley.DgnPlatformNET;
using Bentley.DgnPlatformNET.Elements;
using Bentley.GeometryNET;
using Bentley.CifNET.LinearGeometry;

namespace ManagedSDKExample
{
    class CorridorItemsTemplateDropCreator : DgnElementSetTool
    {
        private Bentley.CifNET.GeometryModel.SDK.Corridor m_corridor;
        private LinearElement m_corridorAlignmentCurve;
        private double m_startDistanceAlong;
        private double m_endDistanceAlong;
        private string m_commandParams;
        private CommandState m_currentCommandState = CommandState.StartOfCommand;

        Bentley.CifNET.GeometryModel.SDK.TemplateDropParameters m_templateDropParams;

        private static uint m_color = 6;
        private static double m_crossLineLength = 200;

        /*----------------------------------------------------------------------------------------------**/
        /* Write Function | The user is prompted to select a corridor, start, and end distance along a corridor
        /*--------------+---------------+---------------+---------------+---------------+----------------*/
        protected override void OnPostInstall()
        {
            base.BeginPickElements();
            AccuSnap.LocateEnabled = true;
            AccuSnap.SnapEnabled = false;
            base.OnPostInstall();
            NotificationManager.OutputPrompt("Select a corridor.");
        }

        protected override bool OnPostLocate(HitPath path, out string cantAcceptReason)
        {
            //checks that hitpath is not null
            if (path == null)
            {
                cantAcceptReason = "HitPath is null.";
                return false;
            }

            //checks that the cursor element is not null
            Element el = path.GetCursorElement();
            if (el == null)
            {
                cantAcceptReason = "There is no element at cursor.";
                return false;
            }

            Bentley.CifNET.GeometryModel.SDK.Corridor tempCorridor = null;
            Bentley.CifNET.SDK.Edit.ConsensusConnectionEdit con = Bentley.CifNET.SDK.Edit.ConsensusConnectionEdit.GetActive();
            tempCorridor = Bentley.CifNET.GeometryModel.SDK.Corridor.CreateFromElement(con, el);

            if (tempCorridor == null)
            {
                cantAcceptReason = "This is not a corridor element.";
                return false;
            }

            cantAcceptReason = String.Empty;
            return true;
        }
        enum CommandState
        {
            StartOfCommand = 0,
            LocalCorridor = 1,
            GetStartDistanceAlong = 2,
            GetEndDistanceAlong = 3,
            GetTemplate = 4,
            GetOtherParameter = 5,
            EndOfCommand = 6
        };

        private void MoveToNextState()
        {
            CommandState currentState = m_currentCommandState;
            CommandState nextState = CommandState.EndOfCommand;
            if (currentState < CommandState.GetOtherParameter)
            {
                nextState = (CommandState)(((int)currentState) + 1);
            }

            if (nextState == CommandState.EndOfCommand)
            {
                ExitTool();
            }
            else
            {
                m_currentCommandState = nextState;
                StartNextState(nextState);
            }
            if (m_currentCommandState == CommandState.GetOtherParameter)
            {
                DoGetOtherParameter(null);
                bool bret = CreateTemplateDrop();
                if (bret)
                {
                    OnRestartTool();
                }
                else
                {
                    ExitTool();
                }
            }
        }

        private void StartNextState(CommandState nextState)
        {
            switch (nextState)
            {
                case CommandState.LocalCorridor:
                    break;
                case CommandState.GetStartDistanceAlong:
                    {
                        NotificationManager.OutputPrompt("Please input template drop start distance along: ");
                        BeginDynamics();
                    }
                    break;
                case CommandState.GetEndDistanceAlong:
                    {
                        NotificationManager.OutputPrompt("Please input template drop  end distance along: ");
                        BeginDynamics();
                    }
                    break;
                case CommandState.GetTemplate:
                    {
                        NotificationManager.OutputPrompt("Click anywhere to use active template: ");
                        EndDynamics();
                    }
                    break;
                case CommandState.GetOtherParameter:
                    {
                        NotificationManager.OutputPrompt("Please input template parameters: ");
                        EndDynamics();
                    }
                    break;
            }
        }

        protected override void OnDynamicFrame(DgnButtonEvent ev)
        {
            //base.OnDynamicFrame(ev);
            if (!(m_currentCommandState == CommandState.GetStartDistanceAlong || m_currentCommandState == CommandState.GetEndDistanceAlong))
            {
                return;
            }

            Bentley.GeometryNET.DPoint3d point = ev.Point;

            Bentley.DgnPlatformNET.DgnModel currentmodel = Bentley.MstnPlatformNET.Session.Instance.GetActiveDgnModel();
            double UPM = currentmodel.GetModelInfo().UorPerMeter;

            point.X /= UPM;
            point.Y /= UPM;
            point.Z /= UPM;

            LinearPoint linePoint = m_corridorAlignmentCurve.ProjectPointOnPerpendicular(point);
            double parameter = linePoint.Parameter;
            double distAlong = linePoint.DistanceAlong;
            distAlong = m_corridorAlignmentCurve.GetDistanceFromParameter(parameter);
            var linePoint1 = m_corridorAlignmentCurve.GetPointAtDistanceOffset(distAlong, m_crossLineLength);
            var linePoint2 = m_corridorAlignmentCurve.GetPointAtDistanceOffset(distAlong, -m_crossLineLength);


            DPoint3d point1 = linePoint1.Coordinates;
            DPoint3d point2 = linePoint2.Coordinates;

            point1.X *= UPM;
            point1.Y *= UPM;
            point1.Z *= UPM;

            point2.X *= UPM;
            point2.Y *= UPM;
            point2.Z *= UPM;

            DPoint3d[] points = new DPoint3d[] { point1, point2 };
            LineStringElement element = new LineStringElement(currentmodel, null, points);

            ElementPropertiesSetter proSetter = new ElementPropertiesSetter();

            proSetter.SetColor(m_color);
            proSetter.Apply(element);

            RedrawElems redrawElems = new RedrawElems();
            redrawElems.SetDynamicsViewsFromActiveViewSet(Bentley.MstnPlatformNET.Session.GetActiveViewport());
            redrawElems.DrawMode = DgnDrawMode.TempDraw;
            redrawElems.DrawPurpose = DrawPurpose.Dynamics;
            redrawElems.DoRedraw(element);

        }

        private bool DoCurrentState(CommandState currentState, Bentley.DgnPlatformNET.DgnButtonEvent ev)
        {
            bool bRent = false;
            switch (currentState)
            {
                case CommandState.LocalCorridor:
                    bRent = DoLocalCorridor(ev);
                    break;
                case CommandState.GetStartDistanceAlong:
                    bRent = DoGetStartDistance(ev);
                    break;
                case CommandState.GetEndDistanceAlong:
                    bRent = DoGetEndDistance(ev);
                    break;
                case CommandState.GetTemplate:
                    bRent = DoGetTemplate(ev);
                    break;
                case CommandState.GetOtherParameter:
                    //bRent = DoGetOtherParameter(ev);
                    break;
            }
            if (bRent)
            {
                MoveToNextState();
            }
            return bRent;
        }

        private double GetDistanceAtPoint(Bentley.GeometryNET.DPoint3d point)
        {
            Bentley.DgnPlatformNET.DgnModel currentmodel = Bentley.MstnPlatformNET.Session.Instance.GetActiveDgnModel();
            double UPM = currentmodel.GetModelInfo().UorPerMeter;

            point.X /= UPM;
            point.Y /= UPM;
            point.Z /= UPM;


            LinearPoint linePoint = m_corridorAlignmentCurve.ProjectPointOnPerpendicular(point);

            double parameter = linePoint.Parameter;
            double distAlong = linePoint.DistanceAlong;
            distAlong = m_corridorAlignmentCurve.GetDistanceFromParameter(parameter);
            return distAlong;
        }
        private bool DoGetStartDistance(Bentley.DgnPlatformNET.DgnButtonEvent ev)
        {
            m_startDistanceAlong = GetDistanceAtPoint(ev.Point);
            return true;
        }

        private bool DoGetEndDistance(Bentley.DgnPlatformNET.DgnButtonEvent ev)
        {
            m_endDistanceAlong = GetDistanceAtPoint(ev.Point);
            return true;
        }

        private bool DoGetTemplate(Bentley.DgnPlatformNET.DgnButtonEvent ev)
        {
            
            //Load template library and get active template
            string templateName = "C:\\ProgramData\\Bentley\\OpenRoads Designer CE 10.11\\Configuration\\Organization-Civil\\_Civil Default Standards - Imperial\\Template Library\\OpenRoadsTemplatesImperial.itl";

            Bentley.CifNET.GeometryModel.SDK.TemplateLibrary templateLibary = Bentley.CifNET.GeometryModel.SDK.TemplateLibrary.Load(templateName);
            if (null == templateLibary) return false;
            Bentley.CifNET.GeometryModel.SDK.TemplateDefinition templateDefinition = templateLibary.ActiveTemplate;
            if (null == templateDefinition) return false;


            m_templateDropParams = new Bentley.CifNET.GeometryModel.SDK.TemplateDropParameters(templateDefinition, m_startDistanceAlong, m_endDistanceAlong);
            return true;
        }

        private bool DoGetOtherParameter(Bentley.DgnPlatformNET.DgnButtonEvent ev)
        {
            m_templateDropParams.Interval = 5.0;
            m_templateDropParams.MinStartTransition = 0.0;
            m_templateDropParams.MinStopTransition = 0.0;
            m_templateDropParams.Desription = "Test create template, These parameters should be gotten interactively";
            return true;
        }

        private bool DoLocalCorridor(Bentley.DgnPlatformNET.DgnButtonEvent ev)
        {
            HitPath hitPath = DoLocate(ev, true, 1);
            if (hitPath == null)
            {
                return false;
            }
            Bentley.DgnPlatformNET.Elements.Element selectedElement = hitPath.GetHeadElement();
            if (selectedElement == null)
            {
                return false;
            }
            Bentley.CifNET.SDK.Edit.ConsensusConnectionEdit con = Bentley.CifNET.SDK.Edit.ConsensusConnectionEdit.GetActive();
            var tempCorridor = Bentley.CifNET.GeometryModel.SDK.Corridor.CreateFromElement(con, selectedElement);
            m_corridor = tempCorridor as Bentley.CifNET.GeometryModel.SDK.Corridor;

            if (null == m_corridor)
            {
                return false;
            }
            m_corridorAlignmentCurve = m_corridor.CorridorAlignment.LinearGeometry;
            if (m_corridorAlignmentCurve == null)
            {
                return false;
            }
            return true;
        }
        public static void InstallNewInstance(string unparsed)
        {
            CorridorItemsTemplateDropCreator cmd = new CorridorItemsTemplateDropCreator(unparsed);
            cmd.InstallTool();
            NotificationManager.OutputPrompt("Please select a corridor. ");
        }

        public CorridorItemsTemplateDropCreator(string unparsed) : base()
        {
            m_commandParams = unparsed;
        }
        protected override bool OnDataButton(Bentley.DgnPlatformNET.DgnButtonEvent ev)
        {
            bool bRent = DoCurrentState(m_currentCommandState, ev);

            return bRent;
        }
        protected override bool OnResetButton(DgnButtonEvent ev)
        {
            ExitTool();
            return true;
        }

        protected override bool OnInstall()
        {
            m_currentCommandState = CommandState.StartOfCommand;
            MoveToNextState();
            return base.OnInstall();
        }

        protected override void ExitTool()
        {
            base.ExitTool();
        }
        protected override void OnRestartTool()
        {
            InstallNewInstance(m_commandParams);
        }

        public override StatusInt OnElementModify(Element element)
        {
            return Bentley.DgnPlatformNET.StatusInt.Error;
        }

        private bool CreateTemplateDrop()
        {
            Bentley.CifNET.SDK.Edit.ConsensusConnectionEdit con = m_corridor.Connection as Bentley.CifNET.SDK.Edit.ConsensusConnectionEdit;
            if (null == con)
            {
                return false;
            }

            con.StartTransientMode();

            var newTemplateDrop = m_corridor.AddTemplateDrop(m_templateDropParams);

            con.PersistTransients();

            return newTemplateDrop != null;
        }
    }

}